package com.alibaba.citrus.ots.unified.inventory.facade.service;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.otsunifiedinventory.model.dto.NykDataCheckerLoadListRequest;
import com.epoch.app.otsunifiedinventory.nykdatachecker.dto.*;
import com.epoch.app.otsunifiedinventory.nykdatachecker.model.NykDataChecker;
import com.epoch.app.otsunifiedinventory.nykdatachecker.service.NykDataCheckerService;

import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.joda.time.DateTime;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Primary
public class NykDataCheckerServiceImpl implements NykDataCheckerService {

    private enum NykMessageTypeEnum {
        ForecastOrder("预报单", 0),
        TransferOrder("调拨单", 1),
        SaleOrder("销售单", 2);

        private final String value;
        private int code;

        NykMessageTypeEnum(String value, int code) {
            this.value = value;
            this.code = code;
        }
    }

    /**
     * 开始处理预报单
     *
     * @param request
     * @return
     */
    @Override
    public StartProcessForecastOrdersResponse startProcessForecastOrders(StartProcessForecastOrdersRequest request) {
        NykDataChecker createData = buildCreateDataRequst(request.getCount(), request.getBatchNo(),
                request.getResponseJson(), request.getTime(), NykMessageTypeEnum.ForecastOrder,
                request.getFromSys(),request.getQueryDate());

        create(createData);
        return new StartProcessForecastOrdersResponse();
    }

    /**
     * 开始处理销售单
     *
     * @param request
     * @return
     */
    @Override
    public StartProcessSaleOrdersResponse startProcessSaleOrders(StartProcessSaleOrdersRequest request) {

        NykDataChecker createData = buildCreateDataRequst(request.getCount(), request.getBatchNo(),
                request.getResponseJson(), request.getTime(), NykMessageTypeEnum.SaleOrder,
                "", request.getQueryDate());

        create(createData);
        return new StartProcessSaleOrdersResponse();
    }

    /**
     * 获取制定某天的调拨单数量
     * @param request
     * @return
     */
    @Override
    public GetOneDayTransferOrdersCountResponse getOneDayTransferOrdersCount(GetOneDayTransferOrdersCountRequest request){
        GetOneDayTransferOrdersCountResponse response = new GetOneDayTransferOrdersCountResponse();

        NykDataCheckerLoadListRequest loadListRequest = new NykDataCheckerLoadListRequest();
        loadListRequest.setQueryDate(request.getDate());
        loadListRequest.setLimit(1000);
        loadListRequest.setType(NykMessageTypeEnum.TransferOrder.value);
        Result<List<NykDataChecker>> listResult = loadList(loadListRequest);
        StringBuilder message  = new StringBuilder();

        if(CollectionUtils.isEmpty(listResult.getResult())){
            response.setCount(0);
            response.setDate(request.getDate());
            message.append("【"+request.getDate()+"】日牛要客拉取调拨单汇总:\n");
            message.append("拉取单量为:【" + 0 + "】单\n");
            response.setMessage(message.toString());
            return response;
        }

        //可能有多个批次，定时任务及手工拉取都会产生记录，取定时任务批次记录，（时间最早）
        List<NykDataChecker> sortedByGmtCreateList = listResult.getResult().stream().sorted(Comparator.comparing(NykDataChecker::getGmtCreate)).collect(Collectors.toList());
        String batchNo = sortedByGmtCreateList.get(0).getBatchNo();
        int totalCount = 0;
        for (NykDataChecker data : sortedByGmtCreateList) {
            if (data.getBatchNo().equals(batchNo)) {
                totalCount += data.getDataCount();
            }
        }
        message.append("【"+request.getDate()+"】日牛要客拉取调拨单汇总:\n");
        message.append("拉取单量为:【" + totalCount + "】单\n");

        response.setDate(loadListRequest.getQueryDate());
        response.setMessage(message.toString());
        response.setCount(totalCount);

        return response;
    }

    /**
     * 获取制定某天的销售单数量
     * @param request
     * @return
     */
    @Override
    public GetOneDaySaleOrdersCountResponse getOneDaySaleOrdersCount(GetOneDaySaleOrdersCountRequest request){
        GetOneDaySaleOrdersCountResponse response = new GetOneDaySaleOrdersCountResponse();

        NykDataCheckerLoadListRequest loadListRequest = new NykDataCheckerLoadListRequest();
        loadListRequest.setQueryDate(request.getDate());
        loadListRequest.setLimit(1000);
        loadListRequest.setType(NykMessageTypeEnum.SaleOrder.value);
        Result<List<NykDataChecker>> listResult = loadList(loadListRequest);
        StringBuilder message  = new StringBuilder();

        if(CollectionUtils.isEmpty(listResult.getResult())){
            response.setCount(0);
            response.setDate(request.getDate());
            message.append("【"+request.getDate()+"】日牛要客拉取销售单汇总:\n");
            message.append("拉取单量为:【" + 0 + "】单\n");
            response.setMessage(message.toString());
            return response;
        }

        //可能有多个批次，定时任务及手工拉取都会产生记录，取定时任务批次记录，（时间最早）
        List<NykDataChecker> sortedByGmtCreateList = listResult.getResult().stream().sorted(Comparator.comparing(NykDataChecker::getGmtCreate)).collect(Collectors.toList());
        String batchNo = sortedByGmtCreateList.get(0).getBatchNo();
        int totalCount = 0;
        for (NykDataChecker data : sortedByGmtCreateList) {
            if (data.getBatchNo().equals(batchNo)) {
                totalCount += data.getDataCount();
            }
        }
        message.append("【"+request.getDate()+"】日牛要客拉取销售单汇总:\n");
        message.append("拉取单量为:【" + totalCount + "】单\n");

        response.setDate(loadListRequest.getQueryDate());
        response.setMessage(message.toString());
        response.setCount(totalCount);

        return response;
    }

    /**
     * 获取制定某天的预报单数量
     * @param request
     * @return
     */
    @Override
    public GetOneDayForcastOrdersCountResponse getOneDayForcastOrdersCount(GetOneDayForcastOrdersCountRequest request){
        GetOneDayForcastOrdersCountResponse response = new GetOneDayForcastOrdersCountResponse();

        NykDataCheckerLoadListRequest loadListRequest = new NykDataCheckerLoadListRequest();
        loadListRequest.setQueryDate(request.getDate());
        loadListRequest.setLimit(1000);
        loadListRequest.setType(NykMessageTypeEnum.ForecastOrder.value);
        Result<List<NykDataChecker>> listResult = loadList(loadListRequest);
        StringBuilder message  = new StringBuilder();

        if(CollectionUtils.isEmpty(listResult.getResult())){
            response.setDate(request.getDate());
            message.append("【"+request.getDate()+"】日牛要客拉取预报单汇总:\n");
            message.append("拉取单量为:【" + 0 + "】单\n");
            response.setMessage(message.toString());
            return response;
        }
        Map<String, Integer> resultMap = new HashMap<>();
        message.append("【"+request.getDate()+"】日牛要客拉取预报单汇总:\n");

        Map<String, List<NykDataChecker>> fromSysGroup = listResult.getResult().stream().collect(Collectors.groupingBy(NykDataChecker::getFromSys));
        for (Map.Entry<String, List<NykDataChecker>> entry : fromSysGroup.entrySet()) {
            List<NykDataChecker> list = entry.getValue();
            //可能有多个批次，定时任务及手工拉取都会产生记录，取定时任务批次记录，（时间最早）
            List<NykDataChecker> sortedByGmtCreateList = list.stream().sorted(Comparator.comparing(NykDataChecker::getGmtCreate)).collect(Collectors.toList());
            String batchNo = sortedByGmtCreateList.get(0).getBatchNo();
            int totalCount = 0;
            for (NykDataChecker data: sortedByGmtCreateList){
                if (data.getBatchNo().equals(batchNo)){
                    totalCount += data.getDataCount();
                }
            }
            resultMap.put(entry.getKey(), totalCount);
            message.append("客户:【"+entry.getKey()+"】拉取单量为:【"+totalCount+"】单\n");
        }

//        response.setMessage(JSONObject.toJSONString(resultMap));
        response.setResult(resultMap);
        response.setDate(loadListRequest.getQueryDate());
        response.setMessage(message.toString());

        return response;
    }

    private NykDataChecker buildCreateDataRequst(Integer count, String batchNo, String dataJson,
                                                 Date processTime, NykMessageTypeEnum type,
                                                 String fromSys, String queryDate) {
        NykDataChecker createData = new NykDataChecker();
        createData.setDataCount(count);
        createData.setBatchNo(batchNo);
        createData.setDataJson(dataJson);
        DateTime dateTime = new DateTime(processTime);
        createData.setProcessTime(dateTime.toString("yyyy-MM-dd hh:mm:SS"));
        createData.setType(type.value);
        createData.setFromSys(fromSys);
        createData.setQueryDate(queryDate);

        return createData;
    }

    /**
     * 开始处理调拨单
     *
     * @param request
     * @return
     */
    @Override
    public StartProcessTransferOrdersResponse startProcessTransferOrders(StartProcessTransferOrdersRequest request) {
        NykDataChecker createData = buildCreateDataRequst(request.getCount(), request.getBatchNo(),
                request.getResponseJson(), request.getTime(), NykMessageTypeEnum.TransferOrder,
                "", request.getQueryDate());

        create(createData);
        return new StartProcessTransferOrdersResponse();
    }

    /**
     * 生成批次号
     * TODO：这里不够严谨，有重复的可能，但概率较小，可以忽略
     *
     * @return
     */
    @Override
    @NotNull
    public GenerateBatchNoResponse generateBatchNo() {
        GenerateBatchNoResponse response = new GenerateBatchNoResponse();
        response.setBatchNo(DateTime.now().toString("yyyyMMdd-HHmmSSsss-") + new Random().nextInt(10000));

        return response;
    }
}
